package com.ai.imagetext.controller;

import com.ai.imagetext.dto.ImageDTO;
import com.ai.imagetext.dto.WorkFlowGenRequest;
import com.ai.imagetext.entity.GeneratedImage;
import com.ai.imagetext.service.ImageService;
import com.alibaba.dashscope.aigc.imagesynthesis.ImageSynthesis;
import com.ai.imagetext.service.ImageGenerationService;
import com.alibaba.dashscope.aigc.imagesynthesis.ImageSynthesisParam;
import com.alibaba.dashscope.aigc.imagesynthesis.ImageSynthesisResult;
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.alibaba.dashscope.utils.JsonUtils;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.reactive.function.client.WebClient;

import java.util.*;


@Slf4j
@RestController
@RequestMapping("/api/image-generation")
@RequiredArgsConstructor
public class ImageGenerationController {

    @Value("${dashscope.api.key}")
    private String apiKey;

    private final ImageGenerationService imageGenerationService;
    private final ImageService imageService;
    /**
     * 工作流生成图片
     */
    @PostMapping("/workflow")
    public ResponseEntity<Map<String, Object>> workflowGeneration(@RequestBody WorkFlowGenRequest request) {
        try {


            // 获取原始图片URL
            Optional<ImageDTO> imageById = imageService.getImageById(request.getImageId());
            imageService.incrementUsageCount(request.getImageId());
            String imageUrl = imageById
                    .map(ImageDTO::getFileUrl)
                    .orElseThrow(() -> new RuntimeException("Image not found"));

            // 构建工作流请求参数
            Map<String, Object> parameters = new HashMap<>();
            parameters.put("BOT_USER_INPUT", "");
            parameters.put("img", imageUrl);
            parameters.put("logo_place","");
            parameters.put("prompt", request.getPrompt());
            parameters.put("propotion",  "");
            parameters.put("qr_img", "");
            parameters.put("qr_place","");

            Map<String, Object> requestBody = new HashMap<>();
            requestBody.put("parameters", parameters);
            requestBody.put("workflow_id", "7529045681714282523");

            // 调用 Coze API
            String result = callCozeWorkflowAPI(requestBody);

            Map<String, Object> response = createSuccessResponse("工作流图片生成任务已启动");
            response.put("data", extractOutputFromSSEResponse(result));
            response.put("message", "工作流图片生成完成");

            return ResponseEntity.ok(response);

        } catch (Exception e) {
            log.error("Workflow image generation failed", e);
            return ResponseEntity.badRequest().body(createErrorResponse(e.getMessage()));
        }
    }

    /**
     * 调用 Coze 工作流 API（完整实现）
     * @author wangguiyou
     * @param requestBody 请求体
     * @return API响应结果
     */
    private String callCozeWorkflowAPI(Map<String, Object> requestBody) {
        try {
            ObjectMapper objectMapper = new ObjectMapper();
            String jsonBody = objectMapper.writeValueAsString(requestBody);

            // 使用WebClient调用API
            WebClient webClient = WebClient.builder()
                    .defaultHeader("Authorization", "Bearer pat_2eI9gVMIJ2X5ssjrhyieNX7qmify7xl0KbGRz2bYd4HtRYxrl59psTxoZz3IznYJ")
                    .defaultHeader("User-Agent", "Apifox/1.0.0 (https://apifox.com)")
                    .defaultHeader("Content-Type", "application/json")
                    .defaultHeader("Accept", "*/*")
                    .defaultHeader("Host", "api.coze.cn")
                    .defaultHeader("Connection", "keep-alive")
                    .build();

            String response = webClient.post()
                    .uri("https://api.coze.cn/v1/workflow/stream_run")
                    .bodyValue(jsonBody)
                    .retrieve()
                    .bodyToMono(String.class)
                    .block();

            log.info("Coze API response: {}", response);
            return response;

        } catch (Exception e) {
            log.error("Failed to call Coze API", e);
            throw new RuntimeException("调用工作流API失败: " + e.getMessage());
        }
    }
    /**
     * 从SSE响应中提取output字段
     * @author wangguiyou
     * @param sseResponse SSE格式的响应数据
     * @return 提取的output URL
     */
    private String extractOutputFromSSEResponse(String sseResponse) {
        try {
            // 按行分割SSE响应
            String[] lines = sseResponse.split("\n");

            for (String line : lines) {
                // 查找包含data的行
                if (line.startsWith("data: ") && line.contains("output")) {
                    // 提取JSON部分
                    String jsonPart = line.substring(6); // 去掉"data: "

                    ObjectMapper mapper = new ObjectMapper();
                    JsonNode rootNode = mapper.readTree(jsonPart);

                    // 检查是否有content字段
                    if (rootNode.has("content")) {
                        String content = rootNode.get("content").asText();

                        // 解析content中的JSON
                        JsonNode contentNode = mapper.readTree(content);

                        // 提取output字段
                        if (contentNode.has("output")) {
                            String output = contentNode.get("output").asText();
                            log.info("Extracted output URL: {}", output);
                            return output;
                        }
                    }
                }
            }

            log.warn("No output found in SSE response");
            return "";

        } catch (Exception e) {
            log.error("Failed to extract output from SSE response", e);
            return "";
        }
    }

    /**
     * 生成相似图片
     */
    @PostMapping("/generate")
    public ResponseEntity<Map<String, Object>> generateSimilarImages(
            @RequestBody ImageGenerationRequest request
    ) throws JsonProcessingException {
        Optional<ImageDTO> imageById = imageService.getImageById(request.getOriginalImageId());
        imageService.incrementUsageCount(request.getOriginalImageId());
        String imageUrl = imageById
                .map(ImageDTO::getFileUrl)  // 获取 url 字段
                .orElseThrow(() -> new RuntimeException("Image not found"));
        String prompt = request.getCustomPrompt();
        String style = request.getStyle();
        if (prompt == null || prompt.isEmpty()) {
            prompt = "发挥想象力，生成与本图片相似的图片，风格为:" + style + "。";
        }else {
            prompt = prompt+"风格为:" + style + "。" ;
        }
        // 设置parameters参数
        Map<String, Object> parameters = new HashMap<>();
        parameters.put("prompt_extend", true);
        //String maskImageUrl = "http://wanx.alicdn.com/material/20250318/description_edit_with_mask_3_mask.png";
        //String baseImageUrl = "http://wanx.alicdn.com/material/20250318/description_edit_with_mask_3.jpeg";
        ImageSynthesisParam param =
                ImageSynthesisParam.builder()
                        .apiKey(apiKey)
                        .model(ImageSynthesis.Models.WANX_V1)
                        .function(ImageSynthesis.ImageEditFunction.STYLIZATION_ALL)
                        .prompt(prompt)
                        .refImage(imageUrl)
                        .n(request.getCount())
                        .size("1024*1024")
                        .parameters(parameters)
                        .build();

        ImageSynthesis imageSynthesis = new ImageSynthesis();
        ImageSynthesisResult result = null;
        try {
            System.out.println("---sync call, please wait a moment----");
            result = imageSynthesis.call(param);
        } catch (ApiException | NoApiKeyException e){
            throw new RuntimeException(e.getMessage());
        }
        String json = JsonUtils.toJson(result);
        log.info("result:{}", json);
        try {

            Map<String, Object> response = createSuccessResponse("图片生成任务已启动");
            response.put("data",extractImageUrlArrayFromJson(json));
            response.put("message", "相似图片生成完成");
            return ResponseEntity.ok(response);

        } catch (Exception e) {
            e.printStackTrace();
        }


        return null;
    }
    private static final String DEFAULT_IMAGE_URL = "http://wanx.alicdn.com/material/20250318/description_edit_with_mask_3.jpeg";


    public static List<String> extractImageUrlArrayFromJson(String json) {
        List<String> result = new ArrayList<>();
        try {
            ObjectMapper mapper = new ObjectMapper();
            JsonNode rootNode = mapper.readTree(json);

            // 检查任务状态是否为 SUCCEEDED
            JsonNode taskStatusNode = rootNode.path("output").path("task_status");
            if (!"SUCCEEDED".equals(taskStatusNode.asText())) {
                result.add(DEFAULT_IMAGE_URL);
                return result;
            }

            // 提取 results 数组
            JsonNode resultsNode = rootNode.path("output").path("results");
            if (resultsNode.isArray() && !resultsNode.isEmpty()) {
                for (JsonNode itemNode : resultsNode) {
                    JsonNode urlNode = itemNode.path("url");
                    if (!urlNode.isMissingNode() && urlNode.isValueNode()) {
                        String url = urlNode.asText();
                        if (!url.isEmpty()) {
                            result.add(url);
                        }
                    }
                }
            }

            // 如果没有提取到有效 url，则返回默认值
            if (result.isEmpty()) {
                result.add(DEFAULT_IMAGE_URL);
            }

        } catch (Exception e) {
            result.clear();
            result.add(DEFAULT_IMAGE_URL);
        }

        return result;
    }


    /**
     * 批量生成相似图片
     */
    @PostMapping("/generate/batch")
    public ResponseEntity<Map<String, Object>> batchGenerateSimilarImages(@RequestBody BatchImageGenerationRequest request) {
        log.info("Batch image generation request for {} images", request.getImageIds().size());

        try {
            // 异步执行批量生成
//            imageGenerationService.batchGenerateSimilarImages(
//                    request.getImageIds(),
//                    request.getCountPerImage(),
//                    request.getStyle(),
//                    request.getCustomPrompt()
//            );

            Map<String, Object> response = createSuccessResponse("批量图片生成任务已启动");
            response.put("imageIds", request.getImageIds());
            response.put("countPerImage", request.getCountPerImage());
            response.put("style", request.getStyle());
            response.put("message", "相似图片正在批量生成中，请稍后查看结果");

            return ResponseEntity.ok(response);

        } catch (Exception e) {
            log.error("Batch image generation failed", e);
            return ResponseEntity.badRequest().body(createErrorResponse(e.getMessage()));
        }
    }

    /**
     * 获取图片的生成记录
     */
    @GetMapping("/original/{originalImageId}")
    public ResponseEntity<Map<String, Object>> getGeneratedImagesForOriginal(@PathVariable Long originalImageId) {
        log.info("Getting generated images for original image: {}", originalImageId);

        try {
            List<GeneratedImage> records = imageGenerationService.getGeneratedImagesForOriginal(originalImageId);
            List<GeneratedImageDTO> dtos = records.stream()
                    .map(this::convertToDTO)
                    .toList();

            Map<String, Object> response = createSuccessResponse("获取生成记录成功");
            response.put("data", dtos);
            response.put("originalImageId", originalImageId);
            response.put("count", dtos.size());

            return ResponseEntity.ok(response);

        } catch (Exception e) {
            log.error("Get generated images for original failed", e);
            return ResponseEntity.badRequest().body(createErrorResponse(e.getMessage()));
        }
    }

    /**
     * 获取生成记录详情
     */
    @GetMapping("/record/{recordId}")
    public ResponseEntity<Map<String, Object>> getGeneratedImageRecord(@PathVariable Long recordId) {
        log.info("Getting generated image record: {}", recordId);

        try {
            GeneratedImage record = imageGenerationService.getGeneratedImageRecord(recordId);
            GeneratedImageDTO dto = convertToDTO(record);

            Map<String, Object> response = createSuccessResponse("获取生成记录详情成功");
            response.put("data", dto);

            return ResponseEntity.ok(response);

        } catch (Exception e) {
            log.error("Get generated image record failed", e);
            return ResponseEntity.badRequest().body(createErrorResponse(e.getMessage()));
        }
    }

    /**
     * 删除生成记录
     */
    @PostMapping("/record/{recordId}/delete")
    public ResponseEntity<Map<String, Object>> deleteGeneratedImageRecord(@PathVariable Long recordId) {
        log.info("Deleting generated image record: {}", recordId);

        try {
            imageGenerationService.deleteGeneratedImageRecord(recordId);

            Map<String, Object> response = createSuccessResponse("删除生成记录成功");
            response.put("recordId", recordId);

            return ResponseEntity.ok(response);

        } catch (Exception e) {
            log.error("Delete generated image record failed", e);
            return ResponseEntity.badRequest().body(createErrorResponse(e.getMessage()));
        }
    }

    /**
     * 重试失败的图片生成
     */
    @PostMapping("/retry-failed")
    public ResponseEntity<Map<String, Object>> retryFailedGenerations() {
        log.info("Retry failed image generations request");

        try {
            // 异步执行重试任务
            imageGenerationService.retryFailedGenerations();

            Map<String, Object> response = createSuccessResponse("重试失败图片生成任务已启动");
            response.put("message", "正在重新生成失败的图片，请稍后查看结果");

            return ResponseEntity.ok(response);

        } catch (Exception e) {
            log.error("Retry failed image generations failed", e);
            return ResponseEntity.badRequest().body(createErrorResponse(e.getMessage()));
        }
    }

    /**
     * 获取图片生成统计信息
     */
    @GetMapping("/statistics")
    public ResponseEntity<Map<String, Object>> getImageGenerationStatistics() {
        log.info("Getting image generation statistics");

        try {
            ImageGenerationService.ImageGenerationStatistics stats = imageGenerationService.getImageGenerationStatistics();

            Map<String, Object> response = createSuccessResponse("获取图片生成统计信息成功");
            response.put("data", stats);

            return ResponseEntity.ok(response);

        } catch (Exception e) {
            log.error("Get image generation statistics failed", e);
            return ResponseEntity.badRequest().body(createErrorResponse(e.getMessage()));
        }
    }

    /**
     * 转换为DTO
     */
    private GeneratedImageDTO convertToDTO(GeneratedImage record) {
        GeneratedImageDTO dto = new GeneratedImageDTO();
        dto.setId(record.getId());
        dto.setOriginalImageId(record.getOriginalImage().getId());

        if (record.getGeneratedImage() != null) {
            dto.setGeneratedImageId(record.getGeneratedImage().getId());
            dto.setGeneratedImageUrl(record.getGeneratedImage().getFileUrl());
        }

        dto.setGenerationPrompt(record.getGenerationPrompt());
        dto.setGenerationParams(record.getGenerationParams());
        dto.setAiGenerationStatus(record.getAiGenerationStatus());
        dto.setSimilarityScore(record.getSimilarityScore());
        dto.setCreatedAt(record.getCreatedAt());
        dto.setUpdatedAt(record.getUpdatedAt());

        return dto;
    }

    /**
     * 创建成功响应
     */
    private Map<String, Object> createSuccessResponse(String message) {
        Map<String, Object> response = new HashMap<>();
        response.put("success", true);
        response.put("message", message);
        response.put("timestamp", System.currentTimeMillis());
        return response;
    }

    /**
     * 创建错误响应
     */
    private Map<String, Object> createErrorResponse(String message) {
        Map<String, Object> response = new HashMap<>();
        response.put("success", false);
        response.put("message", message);
        response.put("timestamp", System.currentTimeMillis());
        return response;
    }

    /**
     * 图片生成请求
     */
    public static class ImageGenerationRequest {
        private Long originalImageId;
        private int count = 3;
        private String style = "auto";
        private String customPrompt;

        // Getters and Setters
        public Long getOriginalImageId() { return originalImageId; }
        public void setOriginalImageId(Long originalImageId) { this.originalImageId = originalImageId; }

        public int getCount() { return count; }
        public void setCount(int count) { this.count = count; }

        public String getStyle() { return style; }
        public void setStyle(String style) { this.style = style; }

        public String getCustomPrompt() { return customPrompt; }
        public void setCustomPrompt(String customPrompt) { this.customPrompt = customPrompt; }
    }

    /**
     * 批量图片生成请求
     */
    public static class BatchImageGenerationRequest {
        private List<Long> imageIds;
        private int countPerImage = 3;
        private String style = "auto";
        private String customPrompt;

        // Getters and Setters
        public List<Long> getImageIds() { return imageIds; }
        public void setImageIds(List<Long> imageIds) { this.imageIds = imageIds; }

        public int getCountPerImage() { return countPerImage; }
        public void setCountPerImage(int countPerImage) { this.countPerImage = countPerImage; }

        public String getStyle() { return style; }
        public void setStyle(String style) { this.style = style; }

        public String getCustomPrompt() { return customPrompt; }
        public void setCustomPrompt(String customPrompt) { this.customPrompt = customPrompt; }
    }

    /**
     * 生成图片DTO
     */
    public static class GeneratedImageDTO {
        private Long id;
        private Long originalImageId;
        private Long generatedImageId;
        private String generatedImageUrl;
        private String generationPrompt;
        private String generationParams;
        private GeneratedImage.AIGenerationStatus aiGenerationStatus;
        private java.math.BigDecimal similarityScore;
        private java.time.LocalDateTime createdAt;
        private java.time.LocalDateTime updatedAt;

        // Getters and Setters
        public Long getId() { return id; }
        public void setId(Long id) { this.id = id; }

        public Long getOriginalImageId() { return originalImageId; }
        public void setOriginalImageId(Long originalImageId) { this.originalImageId = originalImageId; }

        public Long getGeneratedImageId() { return generatedImageId; }
        public void setGeneratedImageId(Long generatedImageId) { this.generatedImageId = generatedImageId; }

        public String getGeneratedImageUrl() { return generatedImageUrl; }
        public void setGeneratedImageUrl(String generatedImageUrl) { this.generatedImageUrl = generatedImageUrl; }

        public String getGenerationPrompt() { return generationPrompt; }
        public void setGenerationPrompt(String generationPrompt) { this.generationPrompt = generationPrompt; }

        public String getGenerationParams() { return generationParams; }
        public void setGenerationParams(String generationParams) { this.generationParams = generationParams; }

        public GeneratedImage.AIGenerationStatus getAiGenerationStatus() { return aiGenerationStatus; }
        public void setAiGenerationStatus(GeneratedImage.AIGenerationStatus aiGenerationStatus) { this.aiGenerationStatus = aiGenerationStatus; }

        public java.math.BigDecimal getSimilarityScore() { return similarityScore; }
        public void setSimilarityScore(java.math.BigDecimal similarityScore) { this.similarityScore = similarityScore; }

        public java.time.LocalDateTime getCreatedAt() { return createdAt; }
        public void setCreatedAt(java.time.LocalDateTime createdAt) { this.createdAt = createdAt; }

        public java.time.LocalDateTime getUpdatedAt() { return updatedAt; }
        public void setUpdatedAt(java.time.LocalDateTime updatedAt) { this.updatedAt = updatedAt; }
    }


}
